自动生成typescript类型声明工具实现详解

您所在的位置:网站首页 js json 转string 自动生成typescript类型声明工具实现详解

自动生成typescript类型声明工具实现详解

2023-04-10 00:11| 来源: 网络整理| 查看: 265

自动生成typescript类型声明工具实现详解

在TypeScript 项目中,我们经常需要使用声明一系列的ts类型。然而,手动写的效率实在太低,编写一个自动生成ts类型的工具可以解放生产力。 实现一个工具将 JSON 数据转换为 TypeScript 类型定义,从而让 TypeScript 项目更高效的开发。

 

一、实现的功能 将 JSON 数据转换为 TypeScript 类型定义。支持嵌套的复杂类型,如数组和对象。支持自定义类型名称和命名空间。支持将转换后的 TypeScript 类型定义保存为文件。

 

二、工具使用方法

1.在线playground使用:在线json转ts类型声明

2.已经发布到npm:my-json-to-ts - npm (npmjs.com)

运行效果如下动图:

安装工具:

npm install -g my-json-to-ts

运行工具:

my-json-to-ts input.json output.ts

其中 input.json 是要转换的 JSON 文件路径,output.ts 是转换后的 TypeScript 文件路径。

--name 类型名称 # 指定转换后的类型名称,默认为 JsonType --namespace 命名空间 # 指定转换后的命名空间,默认为无 --no-file # 不将转换后的 TypeScript 类型定义保存为文件

 

三、实现思路 读取输入的 JSON 文件,解析成 JSON 对象。遍历 JSON 对象,根据不同的类型生成对应的 TypeScript 类型定义字符串。如果指定了类型名称和命名空间,则在生成的 TypeScript 类型定义字符串前面添加对应的声明。如果指定了保存文件,则将生成的 TypeScript 类型定义字符串写入文件。

 

四、使用示例

以下是将JSON 数据和转换后的 TypeScript 类型定义示例:

简单的JSON 数据 { "name": "John", "age": 30, "address": { "city": "New York", "state": "NY" }, "hobbies": [ "reading", "traveling" ] } 输出对应简单的类型定义 interface JsonType { name: string; age: number; address: { city: string; state: string; }; hobbies: string[]; } ✈复杂的JSON 数据 { "name": "John", "age": 30, "address": { "city": "New York", "state": "NY", "postalCode": 10001 }, "friends": [ { "name": "Jane", "age": 28, "address": { "city": "Los Angeles", "state": "CA" } }, { "name": "Bob", "age": 35, "address": { "city": "Chicago", "state": "IL" } } ], "hobbies": [ "reading", "traveling", { "name": "swimming", "location": "pool" } ] } ✈输出对应复杂类型定义 interface JsonType { name: string; age: number; address: { city: string; state: string; postalCode: number; }; friends: { name: string; age: number; address: { city: string; state: string; }; }[]; hobbies: (string | { name: string; location: string; })[]; }

 

五、具体实现代码

首先引入两个 Node.js 模块:fs-extra 和 commander。fs-extra 是一个简化了 Node.js 文件系统模块的封装,而 commander 是一个命令行工具的库,可以方便地解析命令行参数。

接下来定义一个函数 jsonToTs,用于将 JSON 数据转换为 TypeScript 类型定义字符串。该函数采用递归的方式遍历 JSON 数据,生成对应的 TypeScript 类型定义。如果 JSON 数据是数组,则递归处理其中的每个元素;如果是对象,则递归处理其中的每个属性。最终,该函数返回一个 TypeScript 类型定义字符串。

然后定义了两个异步函数,readJson 和 writeTs,分别用于读取 JSON 文件和将 TypeScript 类型定义字符串写入文件。

最后定义一个名为 jsonToTsFile 的函数,该函数接收命令行参数并将其传递给 jsonToTs 函数,然后将生成的 TypeScript 类型定义字符串保存到文件中。如果命令行参数中指定了不保存文件,则该函数将直接将 TypeScript 类型定义字符串输出到控制台。

const fs = require('fs-extra'); const commander = require('commander'); /** * 将 JSON 数据转换为 TypeScript 类型定义 * @param {Object} object - 要转换的 JSON 对象 * @param {string} [name=JsonType] - 转换后的类型名称 * @param {string} [namespace] - 转换后的命名空间 * @returns {string} - 转换后的 TypeScript 类型定义字符串 */ function jsonToTs(object, name = 'JsonType', namespace) { const getType = value => { let typeRes = ``; if (Array.isArray(value)) { value.forEach(item => { let subType = getType(item); if (typeRes.split('|').indexOf(subType) < 0) { typeRes += subType typeRes += "|" } }) typeRes = typeRes.substring(0, typeRes.length - 1) if (typeRes.split('|').length > 1) { return `(${typeRes})[]`; } else { return `${typeRes}[]`; } } if (typeof value === 'object' && value !== null) { const props = Object.entries(value) .map(([key, val]) => `${key}: ${getType(val)}`) .join('; '); return `{ ${props} }`; } return typeof value; }; const type = getType(object); const declaration = `interface ${name} ${type}`; return namespace ? `namespace ${namespace} { \r\n ${declaration} \r\n}` : declaration; } /** * 读取文件并解析成 JSON 对象 * @param {string} path - 文件路径 * @returns {Promise} - JSON 对象 */ async function readJson(path) { const content = await fs.readFile(path, 'utf8'); return JSON.parse(content); } /** * 将 TypeScript 类型定义字符串写入文件 * @param {string} content - TypeScript 类型定义字符串 * @param {string} path - 文件路径 * @returns {Promise} */ async function writeTs(content, path) { await fs.writeFile(path, content, 'utf8'); } /** * 将 JSON 数据转换为 TypeScript 类型定义 * @param {string} inputPath - 输入 JSON 文件路径 * @param {string} outputPath - 输出 TypeScript 文件路径 * @param {string} [options.name=JsonType] - 转换后的类型名称 * @param {string} [options.namespace] - 转换后的命名空间 * @param {boolean} [options.noFile] - 不将 TypeScript 类型定义保存为文件 * @returns {Promise} */ async function jsonToTsFile(inputPath, outputPath, options) { const { name, namespace, noFile } = options try { const object = await readJson(inputPath); const type = jsonToTs(object, name, namespace); if (noFile) { console.log(type); } else { await writeTs(type, outputPath); console.log(`Type definition saved to ${outputPath}`); } } catch (err) { console.error(err.message); } } const program = new commander.Command(); program .arguments(' ') .option('--no-file', 'do not save to file') .option('-s, --namespace ', 'type namespace') .option('-n, --name ', 'type name', 'JsonType') .action(jsonToTsFile); program.parse(process.argv);

 

六、写在最后

这个工具可以极大地提高在 TypeScript 项目中编写类型声明的效率。通过输入一个 JSON 数据,它可以自动生成对应的 TypeScript 类型定义,支持复杂类型,如数组和对象,并支持自定义类型名称和命名空间。此外,还可以选择将转换后的 TypeScript 类型定义保存为文件。

以上就是自动生成typescript类型声明工具实现详解的详细内容,更多关于自动生成typescript类型声明的资料请关注编程宝库其它相关文章!

下一节:VueJs中的shallowRef与shallowReactive函数使用比较JS 编程技术

 前言在vue3当中一些相似的组合式API,如果没有经常使用,就会混淆,对于初学者,很是迷惑,比如:shallowRef与shallowReactiv ...



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3